#ifndef __PHONG__
#define __PHONG__

#include "..\Material\Material.h"
#include "..\BRDF\Specular.h"
#include "..\BRDF\Lambertian.h"
#include "..\Light\Light.h"
#include "..\CoreClasses\GeometricObjects\GeometricObjects.h"

namespace Engine
{
	class Phong : public Engine::Material
	{

	public:
		Phong() : diffuseBRDF(new Engine::Lambertian), specularBRDF(new Engine::Specular)
		{}

		Phong(float p_kd, float p_ks, RGBColor p_color) : diffuseBRDF(new Engine::Lambertian), specularBRDF(new Engine::Specular)
		{
			SetCd(p_color);
			SetCs(p_color);
			SetKd(p_kd);
			SetKs(p_ks);
			m_type = GLOSSY;
		}

		Phong(float p_kd, float p_ks, RGBColor p_DiffuseColor, RGBColor p_ReflecColor) : diffuseBRDF(new Engine::Lambertian), specularBRDF(new Engine::Specular)
		{
			SetCd(p_DiffuseColor);
			SetCs(p_ReflecColor);
			//diffuse constant 
			SetKd(p_kd);
			//reflective constant
			SetKs(p_ks);
			m_type = GLOSSY;
		}

		


		void SetCd(RGBColor& p_color)
		{
			diffuseBRDF->SetColor(p_color);
		}

		void SetCs(RGBColor& p_color)
		{
			specularBRDF->SetColor(p_color);
		}

		RGBColor GetMatteColor()
		{
			return diffuseBRDF->GetColor();
		}

		void SetKd(float p_Kd)
		{
			diffuseBRDF->SetKd(p_Kd);
		}

		void SetKs(float p_Ks)
		{
			specularBRDF->SetKs(p_Ks);
		}
		/*sing Engine::Material::areaLightShade;
		RGBColor AreaLightShade(ShadeRec& sr)
		{
		return RGBColor(0);
		}

		using Engine::Material::PathShader;
		RGBColor PathShader(ShadeRec& sr)
		{
		return RGBColor(0);
		}*/

		using Engine::Material::Shade;
		RGBColor Shade(ShadeRec& sr, std::vector<Light*>& sceneLights, Tracer* p_tracerPtr, RGBColor& p_colorAtPoint, Light* p_ambientLight = NULL)
		{
			Point3D w0 = -sr.ray.d;
			//Point3D w0Reflection =
			//ShadowTester testForShadow();
			RGBColor outputColor(0);

			for (int indexLight = 0; indexLight < sceneLights.size(); indexLight ++)
			{
				Point3D wi = sceneLights[indexLight]->GetDirection(sr);
				//ShadowRay shadowTestRay();


				wi.normalize();
				float n_dot_wi = DOT(sr.normal, wi);

				if (n_dot_wi > 0)
				{
					//need to test for shadows
					RGBColor diffuseBrdfComponent = diffuseBRDF->f(sr, wi, w0, p_colorAtPoint,m_containsTexture);
					RGBColor sceneLightComponent = sceneLights[indexLight]->L(sr) * n_dot_wi;

					RGBColor diffuseLightAddition = diffuseBrdfComponent * sceneLightComponent;
					outputColor = outputColor + diffuseLightAddition;
				}

				if (specularBRDF->GetKs() > 0)
				{
					Point3D N = sr.object->GetNormal(sr.localHitPoint);
					N.normalize();
					w0 = 2 * N.dot(wi) * N - wi;
					outputColor = outputColor + specularBRDF->f(sr, wi, w0,p_colorAtPoint, m_containsTexture) * n_dot_wi;
				}
			}

			return outputColor;
		}

	private:
		Engine::Lambertian* diffuseBRDF;
		Engine::Specular* specularBRDF;

	};

}



#endif // !__PHONG__
